/*
 * Copyright (C) 2010 Jens Bierschenk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.algorithmlaboratory;

public abstract class AbstractTreeNode<E extends Comparable<E>> {

	private AbstractTreeNode<E> parent;
	private AbstractTreeNode<E> left;
	private AbstractTreeNode<E> right;
	private E value;
	
	/**
	 * Create a tree node with parent and value
	 * @param parent this node's parent, or {@code null} if this node has no parent
	 * @param value that should be saved
	 * @throws NullPointerException if the parameter value is {@code null}
	 */
	public AbstractTreeNode(AbstractTreeNode<E> parent, E value) {
		if(value == null){
			throw new NullPointerException( "The node should be contain a value." );
		}
		this.parent = parent;
		this.value = value;
	}
	
	/**
	 * Set the node's value
	 * @param value the new value of the node
	 * @throws NullPointerException if the parameter value is {@code null}
	 */
	public void setValue(E value){
		if(value == null){
			throw new NullPointerException( "The node should be contain a value." );
		}
		this.value = value;
	}
	
	/**
	 * Set the node's left side
	 * @param leftNode the new left node of the node
	 */
	public void setLeftNode(AbstractTreeNode<E> leftNode) {
		this.left = leftNode;
	}
	
	/**
	 * Set the node's right side
	 * @param rightNode the new right node of the node
	 */
	public void setRightNode(AbstractTreeNode<E> rightNode) {
		this.right = rightNode;
	}
	
	/**
	 * Set the node's parent node
	 * @param parentNode the new parent node of the node
	 */
	public void setParentNode(AbstractTreeNode<E> parentNode){
		this.parent = parentNode;
	}
	
	/**
	 * Returns the node's value which is actually saved.
	 * @return the node's value which is actually saved
	 */
	public E getValue(){
		return value;
	}
	
	/**
	 * Returns this node's parent or {@code null} if this node has no parent. 
	 * @return this node's parent, or {@code null} if this node has no parent
	 */
	public AbstractTreeNode<E> getParentNode() {
		return parent;
	}
	
	/**
	 * Returns this node's left node or {@code null} if this node has no left side
	 * @return this node's left node or {@code null} if this node has no left side
	 */
	public AbstractTreeNode<E> getLeftNode() {
		return left;
	}
	
	/**
	 * Returns this node's right node or {@code null} if this node has no right side
	 * @return this node's right node or {@code null} if this node has no right side
	 */
	public AbstractTreeNode<E> getRightNode() {
		return right;
	}
}
